using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Middleware
{
    /// <summary>
    /// 安全头中间件 - 添加安全相关的HTTP头
    /// </summary>
    public class SecurityHeadersMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILogger<SecurityHeadersMiddleware> _logger;
        private readonly SecurityHeadersOptions _options;

        public SecurityHeadersMiddleware(
            RequestDelegate next, 
            ILogger<SecurityHeadersMiddleware> logger,
            SecurityHeadersOptions? options = null)
        {
            _next = next;
            _logger = logger;
            _options = options ?? new SecurityHeadersOptions();
        }

        public async Task InvokeAsync(HttpContext context)
        {
            // 添加安全头
            AddSecurityHeaders(context.Response);
            
            // 处理CORS预检请求
            if (context.Request.Method == "OPTIONS")
            {
                await HandlePreflightRequestAsync(context);
                return;
            }

            await _next(context);
            
            // 响应后添加额外的安全头
            AddPostProcessHeaders(context);
        }

        private void AddSecurityHeaders(HttpResponse response)
        {
            // X-Content-Type-Options - 防止MIME类型嗅探
            if (_options.AddXContentTypeOptions)
            {
                response.Headers["X-Content-Type-Options"] = "nosniff";
            }

            // X-Frame-Options - 防止点击劫持
            if (_options.AddXFrameOptions)
            {
                response.Headers["X-Frame-Options"] = _options.XFrameOptionsValue;
            }

            // X-XSS-Protection - XSS保护
            if (_options.AddXXssProtection)
            {
                response.Headers["X-XSS-Protection"] = _options.XXssProtectionValue;
            }

            // Strict-Transport-Security - 强制HTTPS
            if (_options.AddStrictTransportSecurity)
            {
                response.Headers["Strict-Transport-Security"] = _options.StrictTransportSecurityValue;
            }

            // Content-Security-Policy - 内容安全策略
            if (_options.AddContentSecurityPolicy && !string.IsNullOrEmpty(_options.ContentSecurityPolicyValue))
            {
                response.Headers["Content-Security-Policy"] = _options.ContentSecurityPolicyValue;
            }

            // Referrer-Policy - 引用政策
            if (_options.AddReferrerPolicy)
            {
                response.Headers["Referrer-Policy"] = _options.ReferrerPolicyValue;
            }

            // Permissions-Policy - 权限政策
            if (_options.AddPermissionsPolicy && !string.IsNullOrEmpty(_options.PermissionsPolicyValue))
            {
                response.Headers["Permissions-Policy"] = _options.PermissionsPolicyValue;
            }

            // X-Permitted-Cross-Domain-Policies - 跨域策略
            if (_options.AddXPermittedCrossDomainPolicies)
            {
                response.Headers["X-Permitted-Cross-Domain-Policies"] = "none";
            }

            // Cache-Control - 缓存控制
            if (_options.AddCacheControl)
            {
                response.Headers["Cache-Control"] = _options.CacheControlValue;
            }

            // X-Robots-Tag - 搜索引擎爬虫控制
            if (_options.AddXRobotsTag)
            {
                response.Headers["X-Robots-Tag"] = _options.XRobotsTagValue;
            }

            // Server - 隐藏服务器信息
            if (_options.RemoveServerHeader)
            {
                response.Headers.Remove("Server");
            }

            // X-Powered-By - 移除技术栈信息
            response.Headers.Remove("X-Powered-By");
            response.Headers.Remove("X-AspNet-Version");
            response.Headers.Remove("X-AspNetMvc-Version");
        }

        private void AddPostProcessHeaders(HttpContext context)
        {
            var response = context.Response;
            
            // 根据内容类型添加特定安全头
            var contentType = response.ContentType?.ToLower();
            
            if (contentType?.Contains("text/html") == true)
            {
                // HTML响应的额外安全措施
                if (_options.AddXContentTypeOptions && !response.Headers.ContainsKey("X-Content-Type-Options"))
                {
                    response.Headers["X-Content-Type-Options"] = "nosniff";
                }
            }
            
            if (contentType?.Contains("application/json") == true)
            {
                // JSON响应的安全措施
                if (_options.PreventJsonHijacking)
                {
                    // 防止JSON劫持（对于敏感数据）
                    response.Headers["X-Content-Type-Options"] = "nosniff";
                }
            }
        }

        private async Task HandlePreflightRequestAsync(HttpContext context)
        {
            var response = context.Response;
            
            // CORS预检请求处理
            if (_options.EnableCors)
            {
                var origin = context.Request.Headers["Origin"].FirstOrDefault();
                if (!string.IsNullOrEmpty(origin) && IsAllowedOrigin(origin))
                {
                    response.Headers.Append("Access-Control-Allow-Origin", origin);
                    response.Headers.Append("Access-Control-Allow-Methods", _options.CorsAllowedMethods);
                    response.Headers.Append("Access-Control-Allow-Headers", _options.CorsAllowedHeaders);
                    response.Headers.Append("Access-Control-Max-Age", _options.CorsMaxAge.ToString());
                    
                    if (_options.CorsAllowCredentials)
                    {
                        response.Headers.Append("Access-Control-Allow-Credentials", "true");
                    }
                }
            }

            response.StatusCode = 204; // No Content
            await response.CompleteAsync();
        }

        private bool IsAllowedOrigin(string origin)
        {
            if (_options.CorsAllowedOrigins == null || !_options.CorsAllowedOrigins.Any())
            {
                return false;
            }

            // 支持通配符匹配
            foreach (var allowedOrigin in _options.CorsAllowedOrigins)
            {
                if (allowedOrigin == "*" || allowedOrigin == origin)
                {
                    return true;
                }
                
                // 简单的通配符匹配（*.example.com）
                if (allowedOrigin.StartsWith("*."))
                {
                    var domain = allowedOrigin.Substring(2);
                    if (origin.EndsWith("." + domain) || origin == domain)
                    {
                        return true;
                    }
                }
            }

            return false;
        }
    }

    /// <summary>
    /// 安全头配置选项
    /// </summary>
    public class SecurityHeadersOptions
    {
        // 基础安全头控制
        public bool AddXContentTypeOptions { get; set; } = true;
        public bool AddXFrameOptions { get; set; } = true;
        public bool AddXXssProtection { get; set; } = true;
        public bool AddStrictTransportSecurity { get; set; } = true;
        public bool AddContentSecurityPolicy { get; set; } = true;
        public bool AddReferrerPolicy { get; set; } = true;
        public bool AddPermissionsPolicy { get; set; } = true;
        public bool AddXPermittedCrossDomainPolicies { get; set; } = true;
        public bool AddCacheControl { get; set; } = true;
        public bool AddXRobotsTag { get; set; } = false;
        public bool RemoveServerHeader { get; set; } = true;
        public bool PreventJsonHijacking { get; set; } = true;

        // 安全头值配置
        public string XFrameOptionsValue { get; set; } = "DENY";
        public string XXssProtectionValue { get; set; } = "1; mode=block";
        public string StrictTransportSecurityValue { get; set; } = "max-age=31536000; includeSubDomains; preload";
        public string ReferrerPolicyValue { get; set; } = "strict-origin-when-cross-origin";
        public string CacheControlValue { get; set; } = "no-cache, no-store, must-revalidate";
        public string XRobotsTagValue { get; set; } = "noindex, nofollow, nosnippet, noarchive";
        
        // CSP策略 - 需要根据应用需求自定义
        public string ContentSecurityPolicyValue { get; set; } = 
            "default-src 'self'; " +
            "script-src 'self' 'unsafe-inline' 'unsafe-eval'; " +
            "style-src 'self' 'unsafe-inline'; " +
            "img-src 'self' data: https:; " +
            "font-src 'self' data: https:; " +
            "connect-src 'self' https:; " +
            "media-src 'self'; " +
            "object-src 'none'; " +
            "child-src 'self'; " +
            "frame-ancestors 'none'; " +
            "base-uri 'self'; " +
            "form-action 'self';";

        // Permissions Policy - 控制浏览器功能
        public string PermissionsPolicyValue { get; set; } = 
            "accelerometer=(), " +
            "camera=(), " +
            "geolocation=(), " +
            "gyroscope=(), " +
            "magnetometer=(), " +
            "microphone=(), " +
            "payment=(), " +
            "usb=()";

        // CORS配置
        public bool EnableCors { get; set; } = true;
        public List<string> CorsAllowedOrigins { get; set; } = new() { "http://localhost:3000", "https://localhost:3000" };
        public string CorsAllowedMethods { get; set; } = "GET, POST, PUT, DELETE, OPTIONS, PATCH";
        public string CorsAllowedHeaders { get; set; } = "Origin, X-Requested-With, Content-Type, Accept, Authorization, X-Request-ID";
        public bool CorsAllowCredentials { get; set; } = true;
        public int CorsMaxAge { get; set; } = 86400; // 24 hours

        /// <summary>
        /// 获取开发环境友好的配置
        /// </summary>
        public static SecurityHeadersOptions Development()
        {
            return new SecurityHeadersOptions
            {
                AddStrictTransportSecurity = false, // 开发环境通常使用HTTP
                ContentSecurityPolicyValue = "default-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' data: https:;", // 更宽松的CSP
                XFrameOptionsValue = "SAMEORIGIN", // 允许同源嵌套
                CorsAllowedOrigins = new List<string> { "*" }, // 开发环境允许所有来源
            };
        }

        /// <summary>
        /// 获取生产环境严格的配置
        /// </summary>
    public static SecurityHeadersOptions Production(List<string>? allowedOrigins = null)
        {
            return new SecurityHeadersOptions
            {
                AddStrictTransportSecurity = true,
                XFrameOptionsValue = "DENY",
                CacheControlValue = "no-cache, no-store, must-revalidate, private",
                CorsAllowedOrigins = allowedOrigins ?? new List<string>(),
                AddXRobotsTag = true, // 生产环境可能需要SEO控制
            };
        }
    }
}
